package com.avic.modules.login.service.impl;

import com.avic.common.service.impl.BaseServiceImpl;
import com.avic.common.utils.QueryHelpPlus;
import com.avic.dozer.service.IGenerator;
import com.avic.exception.BadRequestException;
import com.avic.modules.log.domain.vo.LogEnumeration;
import com.avic.modules.log.domain.vo.LogVo;
import com.avic.modules.log.service.LogsService;
import com.avic.modules.login.domain.LoginLog;
import com.avic.modules.login.service.LoginLogService;
import com.avic.modules.login.service.dto.LoginLogDto;
import com.avic.modules.login.service.dto.LoginLogQueryCriteria;
import com.avic.modules.login.service.mapper.LoginLogMapper;
import com.avic.modules.system.domain.Dept;
import com.avic.modules.system.domain.User;
import com.avic.modules.system.service.mapper.DeptMapper;
import com.avic.modules.system.service.mapper.SysUserMapper;
import com.avic.utils.FileUtil;
import com.avic.utils.RedisUtils;
import com.avic.utils.SecurityUtils;
import com.avic.utils.StringUtils;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

@Service
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class LoginLogServiceImpl extends BaseServiceImpl
        <LoginLogMapper, LoginLog> implements LoginLogService {

    private final IGenerator generator;
    private final LoginLogMapper loginLogMapper;
    private final SysUserMapper sysUserMapper;
    private final DeptMapper deptService;
    private final RedisUtils redisUtils;
    private final LogsService logsService;

    @Override
    public Map<String, Object> queryAll(LoginLogQueryCriteria criteria, Pageable pageable) {
        String order = "login_time desc";
        getPageSort(pageable,order);
        PageInfo<LoginLog> page = new PageInfo<>(queryAll(criteria));
        List<LoginLogDto> convert = generator.convert(page.getList(), LoginLogDto.class);
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content",convert);
        map.put("totalElements", page.getTotal());
        return map;
    }

    @Override
    public List<LoginLog> queryAll(LoginLogQueryCriteria criteria) {
        List<LoginLog> list = baseMapper.selectList(QueryHelpPlus.getPredicate(LoginLog.class, criteria));
        return list;
    }

    @Override
    public List<LoginLog> queryAllS(LoginLogQueryCriteria criteria, Pageable pageable) {
        String order = "login_time desc";
        getPageSize(pageable,order);
        List<LoginLog> list = baseMapper.selectList(QueryHelpPlus.getPredicate(LoginLog.class, criteria));
        return list;
    }

    @Override
    public void addSave(HttpServletRequest request) {
        LoginLog loginLog = new LoginLog();
        try {
            String ip = StringUtils.getIp(request);
            User user = sysUserMapper.selectById(SecurityUtils.getUserId());
            loginLog.setDeptId(user.getDeptId());
            Dept dept = deptService.selectById(user.getDeptId());
            loginLog.setIpAddress(ip);
            loginLog.setUsername(user.getUsername());
            if(dept!=null){
                loginLog.setDeptName(dept.getName());
            }
            loginLog.setUserId(user.getId());
            loginLog.setCreateUserId(user.getId());
            loginLog.setLoginTime(new Timestamp(System.currentTimeMillis()));
            loginLog.setCreateTime(new Timestamp(System.currentTimeMillis()));
        } catch (BadRequestException e) {
            throw new BadRequestException("登录状态已过期");
        }
        String replace = UUID.randomUUID().toString().replace("-", "");
        redisUtils.set("LOGINLOGID",replace);
        loginLog.setId(replace);
        loginLog.setIsDeleted(0);
        loginLogMapper.insert(loginLog);
    }

    @Override
    public void download(List<LoginLogDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        long sum = 1;
        for (LoginLogDto role : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("序号", sum);
            map.put("用户名",role.getUsername());
            map.put("部门名称",role.getDeptName());

            map.put("IP",role.getIpAddress());
            if(role.getLoginTime()==null){
                map.put("登录时间",role.getLoginTime());
            }else {
                String s = role.getLoginTime().toString();
                String substring = s.substring(0, s.length() - 2);
                map.put("登录时间",substring);
            }

            if(role.getOfflineTime()==null){
                map.put("下线时间","-");
            }else {
                String s = role.getOfflineTime().toString();
                String substring = s.substring(0, s.length() - 2);
                map.put("下线时间",substring);
            }
            sum ++;
            list.add(map);
        }
        String name = "[导出]了"+ "[登录日志]";
        LogVo logVo = new LogVo();
        logVo.setAction(LogEnumeration.LEADING_OUT.getMessage());
        logVo.setBehavior(name);
        logsService.save(logVo);
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void updateSave(HttpServletRequest request) {

        try {
            LoginLog loginLog = new LoginLog();
            String loginlogid = redisUtils.get("LOGINLOGID").toString();
            loginLog.setId(loginlogid);
            loginLog.setUpdateUserId(SecurityUtils.getUserId());
            loginLog.setOfflineTime(new Timestamp(System.currentTimeMillis()));
            loginLogMapper.updateById(loginLog);
            redisUtils.del("LOGINLOGID");
        } catch (BadRequestException e) {
            throw new BadRequestException("登录状态已过期");
        }
    }
}
